import sys
from time import sleep, localtime
from weakref import WeakKeyDictionary

from PodSixNet.Server import Server
from PodSixNet.Channel import Channel



import jplur
from jplur.login import login
from jplur.intro import intro
from jplur.objects import *
from jplur.create import create
from jplur.monster_gen import Generator as monster_generator
from jplur.construct_map import game_map
from jplur.map_fairy import mapFairy

from jplur.menu import * #client channel passes self to these

class unique_id:
	def __init__(self):
		self.counter = 0
	def new(self):
		self.counter += 1
		return self.counter

class ClientChannel(Channel):
	"""
	This is the server representation of a single connected client.
	"""
	def __init__(self, *args, **kwargs):
		
		self.nickname = "anonymous"
		self.password = "guest"
		self.status = 0
		self.dopple = 0
		self.logged = 0
		self.new = 0
		Channel.__init__(self, *args, **kwargs)
		
		self.menu = [0,0] #menu number, and state of interaction
		menu_login(self)
		
	
	def Close(self):
		print "client.Close()"
		if "player" in self.__dict__:
			self.player.delete()
		self._server.DelPlayer(self)

	def sendLine(self, line):
		self.Send({"action":"message", "data": line})
	
	def handle_esc_commands(self, data):
		print "ESC_COMMAND: ", data
	##################################
	### Network specific callbacks ###
	##################################

	def Network_message(self, data):
		if self.menu[0] != 0:
			if self.menu[0] == 1:
				menu_login(self, data['data'])
			if self.menu[0] == 2:
				menu_look(self, data['data'])
			if self.menu[0] == 3:
				menu_die(self, data['data'])
			if self.menu[0] == 4:
				menu_run(self, data['data'])
			if self.menu[0] == 5:
				menu_dig(self, data['data'])
		else: #not inside a menu dialogue
			print "normal message", self.logged
			if self.logged == 1:
				if data['data'][:1] == "/":
					self.handle_esc_commands(self, data['data'])
				else:
					chat = self.name+":"+data['data']
					self._server.SendToAll({"action": "message", "data": chat})
			
			
				
	def Network_C(self, data):
		print data
		if self.menu[0] != 0:
			if self.menu[0] == 1:
				menu_login(self, data['data'])
			if self.menu[0] == 2:
				menu_look(self, data['data'])
			if self.menu[0] == 3:
				menu_die(self, data['data'])
			if self.menu[0] == 4:
				menu_run(self, data['data'])
			if self.menu[0] == 5:
				menu_dig(self, data['data'])
		else: #not inside a menu dialogue
			if data['data'] == 63:
				menu_help(self)
			if data['data'] == 64:
				menu_who(self)
			if data['data'] == 108:
				menu_look(self)
			if data['data'] == 114:
				menu_run(self)
			if data['data'] == 100:
				menu_dig(self)
			if data['data'] == 113: #q
				self.player.delete()
			if data['data'] in [55,56,57,52,54,49,50,51,   60,62]:
				if "player" in self.__dict__:
					self.player.movekey(data['data'])
	

class ChatServer(Server):
	channelClass = ClientChannel
	
	def __init__(self, *args, **kwargs):
		Server.__init__(self, *args, **kwargs)
		self.players = WeakKeyDictionary()
		jplur.monsters = []
		jplur.unique_id = unique_id()
		jplur.server = self
		jplur.map = game_map()
		jplur.monster_generator = monster_generator()
		jplur.fairy = mapFairy()
		jplur.players = []
		print 'Server launched'
	
	def Connected(self, channel, addr):
		self.AddPlayer(channel)
	
	def AddPlayer(self, player):
		print "New Player" + str(player.addr)
		self.players[player] = True
		self.SendPlayers()
		print "players", [p for p in self.players]
	
	def DelPlayer(self, player):
		print "Deleting Player" + str(player.addr)
		
		if player in self.players:
			del self.players[player]
			print "deleted channel"

	
	def SendPlayers(self):
		pass
		#self.SendToAll({"action": "players", "players": [p.nickname for p in self.players]})
	
	def SendToAll(self, data):
		[p.Send(data) for p in self.players]
	
	def Launch(self):
		while True:
			self.Pump()
			for entry in jplur.monsters:
				entry.pump()
			for entry in jplur.players:
				try:
					entry.pump()

				except:
					pass
			jplur.fairy.pump()
			sleep(0.0001)

# get command line argument of server, port
def Main():
	host, port = ['localhost', 5071]
	s = ChatServer(localaddr=(host, int(5071)))
	s.Launch()


if __name__== '__main__':
	Main()

